package org.uam.util.lock.service.impl;

import java.util.Date;

import org.apache.commons.lang.time.DateUtils;
import org.uam.common.ConstantsUtil;
import org.uam.util.DateAS;
import org.uam.util.lock.dao.LockRechargerAS;
import org.uam.util.lock.service.LockRecharger;


/**
 *
 * <一句话功能简述>
 * <功能详细描述>
 *
 * @author  wkf63324
 * @version  [版本号, 2012-3-8]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
public class LockRechargerImpl implements LockRecharger
{

    /**
     * 获取调测日志
     */
//    private static final CCEngineLog LOGGER = CCEngineLogFactory.getLog(LockRechargerImpl.class);

    /**
     * 充值用户被锁时最大尝试次数
     */
    private static final int DEFAULT_MAX_TRY_TIMES = 5;

    /**
     * 充值用户每次尝试的毫秒间隔
     */
    private static final int DEFAULT_TRY_DELAY_MILLISECOND = 100;

    /**
     * 清理的时间间隔
     */
    private static final int DEFAULT_ALLOWED_INTERVALMINS = 3;

    /**
     * 充值用户锁定原子服务
     */
    private LockRechargerAS lockRechargerAS;

    /**
     * {@inheritDoc}
     * @throws Exception
     * @throws Exception
     */
    public boolean lockRecharger(String userId) throws Exception
    {
        clearTask();
        // 充值用户被锁时最大尝试次数
        int maxTryTimes = DEFAULT_MAX_TRY_TIMES;
        // 充值用户每次尝试的时间间隔（毫秒）
        int tryDelayMillisecond = DEFAULT_TRY_DELAY_MILLISECOND;
        // 已尝试次数
        int tryTimes = ConstantsUtil.NUMBER_00;
        while (true)
        {
            tryTimes++;
            try
            {
                Date lockTime = DateAS.getCurrentTime();
                // 插入锁
                lockRechargerAS.addRechargerLock(userId, lockTime);
                return false;
            }
//            catch (com.huawei.bme.common.IllegalArgumentException e1)
//            catch (Exception e1)
//            {
//                // 参数校验出错
//                String errorMsg = e1.getMessage();
//                if (!"".equals(errorMsg))
//                {
//                    LOGGER.error(errorMsg, e1, new Object[0]);
//                    throw new BMEException(ConstantsUtil.RECHARGELOCK_ERROR,
//                        "The user's latest Recharge is processing.", e1);
//                }
//                errorMsg = "The Date is illeagal!";
//                LOGGER.error(errorMsg, e1, new Object[0]);
//                throw new BMEException(ConstantsUtil.RECHARGELOCK_ERROR, "The user's latest Recharge is processing.",
//                    e1);
//            }
//            catch (BMEException e2)
            catch (Exception e2)
            {
                // 被锁定
                if (tryTimes == maxTryTimes)
                {
                    String errorMsg = "The Recharger is locked for subsequent subscription!";
//                    LOGGER.error(errorMsg, e2, new Object[0]);
                    // ResultCodeConstants.SOAP_RECHARGER_LOCKED
                    // 暂时用 SOAP_OTHER_REASON 7999 代替
//                    throw new BMEException(ConstantsUtil.RECHARGELOCK_COLLISION,
//                        "The user's latest Recharge is processing.", e2);
                    throw new Exception("用户被锁定",e2);
                }
                else
                {
                    // 休眠后再尝试
                    try
                    {
                        Thread.sleep(tryDelayMillisecond);
                        continue;
                    }
                    catch (InterruptedException e1)
                    {
                        // Interruption should be ignored
//                        LOGGER.error("Sleep for lock Recharger is Interrupted.", e1, new Object[] {});
                    }
                }
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    public void unlockRecharger(String userId)
    {
        lockRechargerAS.deleteRechargerByUserId(userId);
        clearTask();
    }

    /**
     * {@inheritDoc}
     */
    public void releaseLongTimeLocked(Date allowedDate)
    {
        lockRechargerAS.deleteLongTimeLocked(allowedDate);
    }

    /**
     * 清理任务（用于取代定时清理任务的实时清理）
     */
    private void clearTask()
    {
        // 允许锁定的时间间隔
        int allowedIntervalMins = DEFAULT_ALLOWED_INTERVALMINS;
        // 允许存在的锁定记录最早锁定时间
        Date allowedDate = DateUtils.addMinutes(DateAS.getCurrentTime(), -allowedIntervalMins);
        // 顺带清理长期锁定的用户
        releaseLongTimeLocked(allowedDate);
    }



    /**
     * <一句话功能简述>
     * <功能详细描述>
     * @return LockRechargerAS lockRechargerAS
     * @see [类、类#方法、类#成员]
     */
    public LockRechargerAS getLockRechargerAS()
    {
        return lockRechargerAS;
    }

    public void setLockRechargerAS(LockRechargerAS lockRechargerAS)
    {
        this.lockRechargerAS = lockRechargerAS;
    }

}
